//
// Created by ttao on 2022/7/21.
//
#include "hash_util.h"

/*
 *  eg: 获取随机序列
    char u[64];
    getBase64(u);
 */
void getBase64(char *dest) {
    int len = 64;
    getRandomHexChars(dest, len);
}

void getRandomHex(char *dest, size_t len) {
    getRandomHexChars(dest, len);
}
void getMd5(char *dest, const char * src) {
    getDataSignHexChars(dest, src, strlen(src));
}

void getSha1(char *dest, const char  *src) {
    getSha1HexChars(dest, src, strlen(src));
}
void getSha256(char *dest, const char  *src) {
    getSha256HexChars(dest, src, strlen(src));
}

int hashcmp(const char *s1, const char *s2)
//若s1=s2，则返回零；若s1<s2，则返回负数；若s1>s2，则返回正数
{
    if(ISNULL(s1) || ISNULL(s2)) return -1;
    return strcmp(s1, s2);
}

char *strcpyautolen(char* s1, char *s2){
    s1 = NULL;
    size_t len_2= strlen(s2);
    s1 = malloc(sizeof(char) * len_2);
    memcpy(s1, s2, len_2);
    s1[len_2] = '\0';
    return s1;
}
struct Queue nodeinputqueue(struct Queue *queue, noder node) {

    task_push(queue, (void *)node);
    if(ISNOTNULL(node) && ISNOTNULL(node->spot->left)) nodeinputqueue(queue, node->spot->left);
    if(ISNOTNULL(node) && ISNOTNULL(node->spot->right)) nodeinputqueue(queue, node->spot->right);
}
BOOL nodeblacknum(int *num, int *rnum, noder node)
// 计算黑高
{
    if(!(node->color^RBTREE_COLOR_BLACK)){
        (*num)++;
        (*rnum) = 0;
    }else{
        (*rnum)++;
        if((*rnum) > 1)
            return FALSE;
    }
    if(!checknodeattr(node, NODE_ATTR_ISROOT)){
        nodeblacknum(num, rnum, node->spot->parent);
    } else return TRUE;
}
BOOL verificationrbtree(Leader *leader)
// 二叉树验证
{
    static int bh = 0;
    static int rn = 0;
    if(ISNULL(leader->root_node)) return TRUE;
    if((leader->root_node->color^RBTREE_COLOR_BLACK)) return FALSE; // 根节点不为黑色直接返回false
    struct Queue queue;
    initQueue(&queue, 100);
    nodeinputqueue(&queue, leader->root_node);
    int afnum = 0;
    for(void * val = task_pop(&queue);val != NULL; val = task_pop(&queue))
    {
        int rnum = 0;
        if(checknodeattr((noder) val, NODE_ATTR_ISLEAF))
        {
            int num = 0;
            if(nodeblacknum(&num, &rnum, val))
            {
                if(afnum != 0 && afnum != num){
                    return FALSE;
                }else{
                    afnum = num;
                    num = 0;
                }
            }else{
                return FALSE;
            }
        }
    }
    return TRUE;
}